﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using AzureContrib.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace MyAnt
{
	public class WorkerRole : RoleEntryPoint
	{
		const string ConsoleTraceListenerSetting = "AzureContrib.Diagnostics.ServiceBusTrace";
		WindowsAzureTraceFactory windowsAzureTraceFactory;
		ITrace Trace;

		public WorkerRole()
		{
			windowsAzureTraceFactory = new WindowsAzureTraceFactory(TraceLevel.Verbose);
			Trace = windowsAzureTraceFactory.Create(GetType());
		}

		public override bool OnStart()
		{
			ServicePointManager.DefaultConnectionLimit = 12;

			RoleEnvironment.Changing += ChangingHandler;

			var value = RoleEnvironment.GetConfigurationSettingValue(ConsoleTraceListenerSetting);

			string servicePath, serviceNamespace, issuerName, issuerSecret;
			if (TryParseCloudTraceListenerSettings(value, out servicePath, out serviceNamespace, out issuerName, out issuerSecret))
			{
				AddCloudTraceListener(servicePath, serviceNamespace, issuerName, issuerSecret);
			}

			return base.OnStart();
		}

		public override void Run()
		{
			Trace.Information("MyAnt entry point called");

			var i = 0;
			while (true)
			{
				Trace.Information("Working in the coal mine {0}.", i++);
				Thread.Sleep(TimeSpan.FromSeconds(1));
			}
		}

		private void ChangingHandler(object sender, RoleEnvironmentChangingEventArgs roleEnvironmentChangingEventArgs)
		{
			string value;
			string servicePath, serviceNamespace, issuerName, issuerSecret;

			if (roleEnvironmentChangingEventArgs.TryGetChangedSetting(ConsoleTraceListenerSetting, out value) &&
					TryParseCloudTraceListenerSettings(value, out servicePath, out serviceNamespace, out issuerName, out issuerSecret))
			{
				RemoveCloudTraceListeners();
				AddCloudTraceListener(servicePath, serviceNamespace, issuerName, issuerSecret);
			}
			else
			{
				RemoveCloudTraceListeners();
			}
		}

		private static void AddCloudTraceListener(string servicePath, string serviceNamespace, string issuerName, string issuerSecret)
		{
			System.Diagnostics.Trace.Listeners.Add(new CloudTraceListener(servicePath, serviceNamespace, issuerName, issuerSecret));
		}

		private static void RemoveCloudTraceListeners()
		{
			var toRemove = System.Diagnostics.Trace.Listeners
																						 .GetEnumerator()
																						 .ToEnumerable<TraceListener>()
																						 .Where(tl => tl is CloudTraceListener)
																						 .ToList();

			foreach (var traceListener in toRemove)
			{
				System.Diagnostics.Trace.Listeners.Remove(traceListener);
			}
		}

		private bool TryParseCloudTraceListenerSettings(string value, out string servicePath, out string serviceNamespace, out string issuerName, out string issuerSecret)
		{
			var parts = value.Split('|');

			if (parts.Length != 4)
			{
				servicePath = null;
				serviceNamespace = null;
				issuerName = null;
				issuerSecret = null;
				return false;
			}

			servicePath = parts[0];
			serviceNamespace = parts[1];
			issuerName = parts[2];
			issuerSecret = parts[3];
			return true;
		}
	}
}